package com.wtwd.device.controller;

import com.alibaba.fastjson.JSONObject;
import com.github.xiaoymin.knife4j.annotations.DynamicParameter;
import com.github.xiaoymin.knife4j.annotations.DynamicParameters;
import com.wtwd.device.constant.Constants;
import com.wtwd.device.constant.RespCode;
import com.wtwd.device.model.entity.DeviceSetting;
import com.wtwd.device.model.entity.DialPlate;
import com.wtwd.device.model.entity.SysRole;
import com.wtwd.device.model.entity.SysUser;
import com.wtwd.device.model.vo.RespEntity;
import com.wtwd.device.service.DeviceSettingService;
import com.wtwd.device.service.DialPlateService;
import com.wtwd.device.service.RedisService;
import com.wtwd.device.service.SysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@Api(tags = "默认表盘管理")
@RestController
@RequestMapping("/dial")
public class DialPlateController {
    private final static Logger logger = LoggerFactory.getLogger(DialPlateController.class);

    @Value("${product.image}")
    private String imgPlace;
    @Value("${file.http}")
    private String fileHttp;
    @Value("${file.path}")
    private String filePath;
    @Value("${dial.preview.image}")
    private String previewImage;
    @Value("${dial.file}")
    private String dialFile;

    @Autowired
    private DialPlateService dialPlateService;
    @Autowired
    private DeviceSettingService deviceSettingService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SysRoleService sysRoleService;

    /**
     * 获取一个手表id的默认表盘
     *
     * @param data
     * @return
     */
    @ApiOperation("修改角色权限列表")
    @DynamicParameters(name = "getDefaultDialPlate", properties = {
            @DynamicParameter(name = "watchId", value = "角色id", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "curPage", value = "当前页", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "pageSize", value = "页面大小", dataTypeClass = Integer.class, required = true)
    })
    @PutMapping("/getDefaultDialPlate")
    public RespEntity getDefaultDialPlate(@RequestBody JSONObject data, HttpServletRequest request) {
        logger.info("/getDefaultDialPlate: data= {}", data.toString());
        String watchId = (String) data.get("watchId");
        Integer curPage = (Integer) data.get("curPage");
        Integer pageSize = (Integer) data.get("pageSize");
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer roleType = (Integer) list.get(1);
        boolean flag = false;
        if (roleType == Constants.SYS_USER_ROLE_TYPE_ADMIN ||roleType == Constants.SYS_USER_ROLE_TYPE_OPERATOR) {
            //管理员可以查看全部
            flag = true;
        } else {
            //根据用户id和手表id查询一笔手表数据
            DeviceSetting deviceSetting = deviceSettingService.getDeviceSettingByWatchIdAndUserId(userId, watchId);
            if (deviceSetting != null) {
                flag = true;
            }
        }
        if (flag) {
            //获取默认表盘
            Map<String, Object> result = dialPlateService.getDefaultDialPlateList(watchId, curPage, pageSize);
            return new RespEntity(RespCode.SUCCESS, result);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 上传表盘预览图文件
     *
     * @param file
     * @param request
     * @return
     */
    @ApiOperation(value = "上传表盘预览图文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "预览图文件", required = true, dataTypeClass = MultipartFile.class)
    })
    @PostMapping("/uploadPreviewImage")
    public RespEntity uploadPreviewImage(@RequestBody MultipartFile file, HttpServletRequest request) {
        logger.info("/uploadPreviewImage");
        String path = filePath.concat(previewImage);
        File saveFile = new File(path);
        if (!saveFile.exists()) {
            //文件不存在则创建一个
            saveFile.mkdir();
        }
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString().concat(originalFilename);
        File dest = new File(path.concat(fileName));
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.SUCCESS, fileName);
    }

    /**
     * 上传表盘文件
     *
     * @param file
     * @param request
     * @return
     */
    @ApiOperation(value = "上传表盘文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "预览图文件", required = true, dataTypeClass = MultipartFile.class)
    })
    @PostMapping("/uploadDialFile")
    public RespEntity uploadDialFile(@RequestBody MultipartFile file, HttpServletRequest request) {
        logger.info("/uploadDialFile");
        String path = filePath.concat(dialFile);
        File saveFile = new File(path);
        if (!saveFile.exists()) {
            //文件不存在则创建一个
            saveFile.mkdir();
        }
        String originalFilename = file.getOriginalFilename();
        String fileName = UUID.randomUUID().toString().concat(originalFilename);
        File dest = new File(path.concat(fileName));
        try {
            file.transferTo(dest);
        } catch (IOException e) {
            e.printStackTrace();
            return new RespEntity(RespCode.FAILED);
        }
        return new RespEntity(RespCode.SUCCESS, fileName);
    }


    /**
     * 添加默认表盘
     *
     * @param dialPlate
     * @param request
     * @return
     */
    @DynamicParameters(name = "addDialPlate", properties = {
             @DynamicParameter(name = "dialName", value = "表盘名", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "shape", value = "表盘类型,表盘形状类型 0：圆形1：方形", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "isShow", value = "是否展示", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "resolution", value = "是否激活", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "previewImg", value = "图片地址", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "watchId", value = "手表id", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "dialOrder", value = "表盘顺序", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "type", value = "表盘类型：0：默认表盘 1：普通表盘", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "dialFile", value = "表盘文件地址", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "editor", value = "是否可编辑 0不可，1可以", dataTypeClass = Integer.class, required = true)
    })
    @PostMapping("/addDialPlate")
    public RespEntity addDialPlate(@RequestBody DialPlate dialPlate, HttpServletRequest request) {
        logger.info("/addDialPlate:dialPlate = {}" + dialPlate.toString());
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer roleType = (Integer) list.get(1);
        boolean b = veryIFCanDo(userId, dialPlate.getWatchId(), roleType);
        if (b) {
            //获取一个可用的表盘顺序
            Integer dialOrder = dialPlateService.getMaxDialPlateOrder(dialPlate.getWatchId());
            if (dialOrder == null) {
                dialOrder = 0;
            }
            dialPlate.setUpdateTime(System.currentTimeMillis());
            dialPlate.setType(Constants.DEFAULT_DIAL_PLATE);
            dialPlate.setDialOrder(dialOrder + 1);
            Integer i = dialPlateService.addDialPlate(dialPlate);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 修改默认表盘
     *
     * @param dialPlate
     * @param request
     * @return
     */
    @DynamicParameters(name = "modifyDialPlate", properties = {
            @DynamicParameter(name = "id", value = "默认表盘id", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "dialName", value = "表盘名", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "shape", value = "表盘类型,表盘形状类型 0：圆形1：方形", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "isShow", value = "是否展示", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "resolution", value = "是否激活", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "previewImg", value = "图片地址", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "watchId", value = "手表id", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "dialOrder", value = "表盘顺序", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "type", value = "表盘类型：0：默认表盘 1：普通表盘", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "dialFile", value = "表盘文件地址", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "editor", value = "是否可编辑 0不可，1可以", dataTypeClass = Integer.class, required = true)
    })
    @PutMapping("/modifyDialPlate")
    public RespEntity modifyDialPlate(@RequestBody DialPlate dialPlate, HttpServletRequest request) {
        logger.info("/modifyDialPlate:dialPlate = {}" + dialPlate.toString());
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer roleType = (Integer) list.get(1);
        //判断是否有权操作
        boolean b = veryIFCanDo(userId, dialPlate.getWatchId(), roleType);
        if (b) {
            dialPlate.setUpdateTime(System.currentTimeMillis());
            Integer i = dialPlateService.modifyDialPlate(dialPlate);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 修改表盘顺序
     *
     * @param data
     * @param request
     * @return
     */
    @DynamicParameters(name = "modifyDialPlateOrder", properties = {
            @DynamicParameter(name = "id", value = "默认表盘id", dataTypeClass = Integer.class, required = true)
            ,@DynamicParameter(name = "watchId", value = "手表型号id", dataTypeClass = String.class, required = true)
            ,@DynamicParameter(name = "dialOrder", value = "手表顺序", dataTypeClass = Integer.class, required = true)
    })
    @PutMapping("/modifyDialPlateOrder")
    public RespEntity modifyDialPlateOrder(@RequestBody JSONObject data, HttpServletRequest request) {
        logger.info("/modifyDialPlateOrder:data = {}" + data.toString());
        Integer id1 = (Integer) data.get("id");
        String watchId = (String) data.get("watchId");
        String orderStr = (String) data.get("dialOrder");
        Integer order = Integer.parseInt(orderStr);
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer roleType = (Integer) list.get(1);
        //判断是否有权操作
        boolean b = veryIFCanDo(userId, watchId, roleType);
        if (b) {
            //判断表盘是否重复
            Integer id = dialPlateService.getDialOrderByWatchIdAndOrder(watchId, order);
            if (id != null && id != id1) {
                return new RespEntity(RespCode.DIAL_PLATE_ORDER_REPEAT);
            }
            //进行表盘顺序修改
            Integer i = dialPlateService.modifyDialOrderById(id1, order);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }

    /**
     * 删除默认表盘
     *
     * @param id
     * @param request
     * @return
     */
    @ApiOperation(value = "删除默认表盘")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "默认表盘id", required = true, dataTypeClass = Integer.class)
    })
    @DeleteMapping("/deleteDefaultDialPlate/{id}")
    public RespEntity deleteDefaultDialPlate(@PathVariable("id") Integer id, HttpServletRequest request) {
        logger.info("/deleteDefaultDialPlate:dialPlate = {}" + id.toString());
        //根据id查找表盘
        DialPlate dialPlate = dialPlateService.getDialPlateById(id);
        if (dialPlate == null) {
            return new RespEntity(RespCode.DIAL_PLATE_NOT_EXIST);
        }
        //获取用户id和角色类型
        List<Object> list = getUserIdAndRoleType(request);
        Long userId = (Long) list.get(0);
        if (userId == 0) {
            return new RespEntity(RespCode.TOKEN_UNAUTHORIZED);
        }
        Integer roleType = (Integer) list.get(1);
        //判断是否有权操作
        boolean b = veryIFCanDo(userId, dialPlate.getWatchId(), roleType);
        if (b) {
            //删除表盘
            Integer i = dialPlateService.deleteDialById(id);
            return new RespEntity(i > 0 ? RespCode.SUCCESS : RespCode.FAILED);
        }
        return new RespEntity(RespCode.NO_RIGHT_OPERATION);
    }


    /**
     * 获取用户id和角色类型
     *
     * @return
     */
    public List<Object> getUserIdAndRoleType(HttpServletRequest request) {
        String token = request.getHeader("Manager-token");
        Map<String, Object> map = redisService.getUserInfoByToken(token);
        if (map == null) {
            return null;
        }
        String str = (String) map.get("user");
        SysUser user = JSONObject.parseObject(str, SysUser.class);
        //根据角色id获取角色类型
        SysRole sysRole = sysRoleService.getSysRoleByRoleId(user.getRoleId());
        Long userId = user.getUserId();
        Integer roleType = sysRole.getRoleType();
        List<Object> list = new ArrayList<>();
        list.add(0, userId);
        list.add(1, roleType);
/*        List<Object> list = new ArrayList<>();
        list.add(0, 4l);
        list.add(1, 3);*/
        return list;
    }

    /**
     * 判断该用户是否有权限操作该手表设置
     *
     * @param userId
     * @param watchId
     * @return
     */
    public boolean veryIFCanDo(Long userId, String watchId, Integer roleType) {
        if (roleType == Constants.SYS_USER_ROLE_TYPE_ADMIN || roleType == Constants.SYS_USER_ROLE_TYPE_OPERATOR) {
            return true;
        }
        //根据用户id查找该用户所属客户下的所有手表id
        List<String> watchIdList = deviceSettingService.getWatchIdByUserId(userId);
        boolean b = watchIdList.contains(watchId);
        return b;
    }

}
